const BaseModel = require('./BaseModel');
const md5 = require('md5');
const createSocketIO = require('../socket/index')
/**
 * 用户ID：md5(account + pwd)
 */

class UserModel extends BaseModel {
  constructor() {
    super();
    this.tableName = 'im_user';
    this.getTableFields(this.tableName).then(fields => {
      this.fields = fields;
    });
    this.userListCache = {};
  }


  /**
   * 
   * 1.登录时为每个用户创建socket连接，用于和每个用户通信
   * 2.创建socket时，先删除之前的socket，因为一个用户只能有一个socket连接，而socket每次都会重新创建
   * 3.接收A用户发给B用的消息，根据数据结构中的account字段，找到B用户的accountID
   * 4.每个用户的socket链接都是固定形式，chat+accountID, 例如：chat1234567890
   * 5.通过accountID，找到socketIds中存储的socket链接，然后向B用户发送消息
   */

  async login(account, pwd) {
    try {
      const _this = this;
      const fields = this.fields.filter(item => {
        return item !== 'pwd';
      }).join(',');

      // 更新在线状态
      const updateOnlineSql = `update ${this.tableName} set online = 1 where account = ? and pwd = ?`;
      this.exec(updateOnlineSql, [account, pwd])

      const sql = `select ${fields} from ${this.tableName} where account = ? and pwd = ?`;
      const params = [account, pwd];
      const results = await this.query(sql, params);
      const data = results[0];

      if (results.length > 0) {
        createSocketIO({
          namespaceName: `users/${results[0].id}`,
          clientEventName: 'receive',
          serverEventName: 'chat',
          userID: results[0].id,
          logoutCallback(userID) {
            console.log('用户退出登录', userID);
            _this.logout(userID);
            clearInterval(_this.userListCache[userID]);
          },
          clientCallback(userID, socketids, clientEventName, data) {
            console.log(`socketids 连接数：${Object.keys(socketids).length}`)
            const { account, msg, time,type } = JSON.parse(data);
            if (!account && msg === '客户端关闭') {
              _this.logout(userID);
              return;
            }
            console.log('====================socket MSG====================', msg, time, clientEventName);
            if (socketids[account]) {
              socketids[account].socket.emit(clientEventName, JSON.stringify({
                msg,
                from: userID,
                time,
                type
              }));
            }

            if (_this.userListCache[userID]) {
              // console.log('刷新了，清空定时器', _this.userListCache[userID])
              clearInterval(_this.userListCache[userID]);
            }
            if (socketids[userID]) {
              _this.userListCache[userID] = setInterval(() => {
                // console.log('正在获取用户列表...')
                _this.getAllUserInfo({
                  username: results[0].username,
                  id: userID,
                }).then(res => {
                  socketids[userID] && socketids[userID].socket.emit('userlist', JSON.stringify(res))
                }, () => {
                  // console.log('获取用户列表失败');
                  clearInterval(_this.userListCache[userID]);
                })
              }, 3000);
            }
          }
        });
        return {
          code: 200,
          msg: '登录成功',
          data
        };
      } else {
        return {
          code: 400,
          msg: '登录失败',
          data: null
        };
      }

    } catch (e) {
      console.log(e)
      return {
        code: 400,
        msg: this.getMysqlErrorMessageByErrno(e.errno)
      };
    }
  }

  async logout(id) {
    try {
      const updateOnlineSql = `update ${this.tableName} set online='0' where id='${id}'`;
      const res = await this.exec(updateOnlineSql, [id])
      if (res.affectedRows > 0) {
        return {
          code: 200,
          msg: '退出成功'
        }
      } else {
        return {
          code: 400,
          msg: '找不到此用户'
        }
      }
    } catch (e) {
      console.log(e);
      return {
        code: 400,
        msg: this.getMysqlErrorMessageByErrno(e.errno)
      };
    }
  }

  async register(postData) {
    try {
      const { account, pwd, photo, sex, username } = postData;
      let sql = '';
      let params = [md5(account + pwd), account, pwd, username];
      if (photo && sex) {
        sql = `insert into ${this.tableName} (id,account,pwd,username,photo,sex) values (?,?,?,?,?,?)`;
        params.push(photo, sex);
      } else if (photo) {
        sql = `insert into ${this.tableName} (id,account,pwd,username,photo) values (?,?,?,?,?)`;
        params.push(photo);
      } else if (sex) {
        sql = `insert into ${this.tableName} (id,account,pwd,username,sex) values (?,?,?,?,?)`;
        params.push(sex);
      } else {
        sql = `insert into ${this.tableName} (id,account,pwd,username) values (?,?,?,?)`;
      }
      const results = await this.query(sql, params);
      if (results.affectedRows > 0) {
        return {
          code: 200,
          msg: '注册成功'
        }
      } else {
        return {
          code: 400,
          msg: '重复注册'
        }
      }
    } catch (e) {
      return {
        code: 400,
        msg: this.getMysqlErrorMessageByErrno(e.errno)
      }
    }
  }

  async getUserInfoById(id) {
    try {
      const sql = `select * from ${this.tableName} where id = ?`;
      const params = [id];
      const results = await this.query(sql, params);
      return {
        code: 200,
        msg: '获取用户信息成功',
        data: results
      };
    } catch (e) {
      return {
        code: 400,
        msg: this.getMysqlErrorMessageByErrno(e.errno)
      }
    }
  }


  // 获取所有用户信息 返回array
  async getAllUserInfo(getData) {
    try {
      const { username, id } = getData
      const fields = this.fields.filter(item => {
        return item !== 'pwd' && item !== 'account';
      }).join(',');
      const sql = `select ${fields} from ${this.tableName} where username != '${username}' and id != '${id}' and state='2'`;
      let results = await this.query(sql);
      return {
        code: 200,
        msg: '获取用户信息成功',
        data: results
      };
    } catch (e) {
      // console.log(e);
      return {
        code: 400,
        msg: this.getMysqlErrorMessageByErrno(e.errno)
      }
    }
  }

  async getUserList(page, pageSize) {
    try {
      const fields = this.fields.filter(item => {
        return item !== 'pwd';
      }).join(',');
      const sql = `select ${fields} from ${this.tableName}`;
      let results = await this.query(sql);
      return {
        code: 200,
        msg: '获取用户信息成功',
        data: results
      };
    } catch (e) {
      return {
        code: 400,
        msg: e.message
      }
    }
  }

  async editorState(id, state) {
    const sql = `update ${this.tableName} set state='${state}' where id='${id}'`;
    const params = [state, id];
    const result = await this.exec(sql, params);
    if (result.affectedRows > 0) {
      return {
        code: 200,
        msg: '修改成功'
      }
    } else {
      return {
        code: 400,
        msg: '修改失败'
      }
    }
  }

  async deleteUser(id) {
    const sql = `delete from ${this.tableName} where id='${id}'`;
    const params = [id];
    const result = await this.exec(sql, params);
    if (result.affectedRows > 0) {
      return {
        code: 200,
        msg: '删除成功'
      }
    } else {
      return {
        code: 400,
        msg: '删除失败'
      }
    }
  }


  async editorUserPhoto(id, photo) {
    try {
      const sql = `update ${this.tableName} set photo=? where id=?`;
      const params = [photo, id];
      const res = await this.exec(sql, params);
      if (res.affectedRows > 0) {
        return {
          code: 200,
          msg: '修改成功'
        }
      } else {
        return {
          code: 400,
          msg: '修改失败'
        }
      }
    } catch (e) {
      return {
        code: 400,
        msg: e.message
      }
    }
  }

}

module.exports = new UserModel();